# encoding=utf-8

"""Definition of the CINTRAUser content type
"""

from zope.interface import implements

from Products.Archetypes import atapi
from Products.ATContentTypes.content import folder
from Products.ATContentTypes.content import schemata
from Products.CMFCore.utils import getToolByName
from Products.Archetypes.public import BaseSchema, Schema, BaseContent

from plone.app.users.userdataschema import IUserDataSchema

from AccessControl import ClassSecurityInfo

from cintra.types.interfaces import ICINTRAUser
from cintra.types.config import PROJECTNAME
from cintra.policy.utils.utils import finalizeSchema

def create_base_of_id(first_name, last_name):
    """ Essa função cria o id do usuário com base
    no seu nome e sobrenome
    Chamada por create_id()
    """
    import re
    pattern = re.compile('[a-z\d]')
    filter_func = lambda c: re.match(pattern, c)
    fname_filtered = filter(filter_func, first_name.lower())
    lname_filtered = filter(filter_func, last_name.lower())
    return fname_filtered[:1] + lname_filtered


def create_id(portal_registration, first_name, last_name):
    """ Essa função testa se o id já está em uso e caso
    afirmativo concatena um número ao id para desambiguação
    Chamada por generateNewId()
    """
    base = create_base_of_id(first_name, last_name)
    new_id = base
    num = 0
    pr = portal_registration
    while not pr.isMemberIdAllowed(new_id):
        num += 1
        new_id = "%s%s" % (base, num)
    return new_id

def create_cintra_user(related_object, user_id, email='', fullname=''):
    pr = getToolByName(related_object, 'portal_registration')
    pm = getToolByName(related_object, 'portal_membership')
    uf = getToolByName(related_object, 'acl_users')
    if email == '':
        email = 'sem@email.com'
    pr.addMember(
        user_id, 'senha1',
        properties={
            'home_url': related_object.get_home_url(),
            'username': user_id,
            'email': email,
            'fullname': fullname,
            'related_object': '/'.join(related_object.getPhysicalPath()),
        },
    )
 
    uf.userSetGroups(user_id, [related_object.getGroup()])
    pm.createMemberArea(member_id=user_id) 

#CINTRAUserSchema = finalizeSchema(folder.ATFolderSchema.copy())
CINTRAUserSchema = finalizeSchema(BaseSchema.copy())
#CINTRAUserSchema = BaseSchema.copy()

class CINTRAUser(BaseContent):
    """CINTRAUser type for CINTRA website"""
    implements(ICINTRAUser)

    meta_type = "CINTRAUser"
    schema = CINTRAUserSchema
    
    security = ClassSecurityInfo()
    
    def getFullName(self):
        return self.getFirstName() + ' ' + self.getLastName()
    
    def get_home_url(self):
        """ Standard method to return the user home url.
        If it is necessary to use a specific method, it can be defined in
        user specific class. """
        return self.absolute_url_path()    
    
    def getGroup(self):
        """ returns the group the user belongs. Must be redefined in the
            subclasses.
        """
       
#    Se for patient, o login sera luizfonseca, senao sera lfonseca.
#    No estagio atual, falta modificar o title. No membership ja 
#    esta criando um usuario com a id certa.
    def at_post_create_script(self):
        """ Esse método é chamado no momento da criação de um objeto da classe.
        Ele cria um membro no acl_users com as informações obtidas da classe filha.
        """
        user_id = self.getId()
        
        pm = getToolByName(self, 'portal_membership')
        member = pm.getMemberById(user_id)
        fullname = self.getFullName()
        email = self.getEmail()
        if member is None:
            create_cintra_user(self, user_id, email=email, fullname=fullname)
    
    #===========================================================================
    # _at_rename_after_creation = True faz com que o metodo generateNewId seja
    # chamado no momento da criação de um novo usuário
    #===========================================================================
    _at_rename_after_creation = True
    def generateNewId(self):
        """ Create an id based on the last name of an user.
        """
        lname = self.getLastName()
        fname = self.getFirstName()
        old_id = self.getId()
        pm = getToolByName(self, 'portal_membership')
        if not pm.getMemberById(old_id):
            pr = getToolByName(self, 'portal_registration')
            return create_id(pr, fname, lname)
        else:
            return old_id

atapi.registerType(CINTRAUser, PROJECTNAME)
